package org.torproject.android;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.torproject.android.service.ITorService;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class CircuitStatus extends Activity implements OnClickListener {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		Debug.startMethodTracing("CircuitStatus");
		setContentView(R.layout.layout_circuitdetails);
		
		mConnection = new ITorServiceConnection();
		bindService();
		
		Button closeButton = (Button) findViewById(R.id.closeButton);
		closeButton.setOnClickListener(this);

		Button mapButton = (Button) findViewById(R.id.mapButton);
		mapButton.setOnClickListener(this);

		Intent intent = getIntent();
		circuit = (Circuit) intent.getParcelableExtra("org.torproject.android.CircuitToClose");

//		TextView idView = (TextView) findViewById(R.id.circuitId);
//		idView.setText(circuit.id);
//
//		TextView statusView = (TextView) findViewById(R.id.circuitStatus);
//		statusView.setText(circuit.status);

		//TextView infoView = (TextView) findViewById(R.id.circuitInfo);
		//infoView.setText(circuit.path);

	}
	
	@Override
	public void onStop() {
		super.onStop();
		Debug.stopMethodTracing();
	}

	public void onClick(View v) {
		if(v.getId() == R.id.closeButton) {
			try {
				mService.closeCircuit(circuit.id);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			finish();
		}
		else if(v.getId() == R.id.mapButton) {
			Intent intent = new Intent(this, RouterMapView.class);
			intent.putExtra("org.torproject.android.CircuitToMap", circuit);
			startActivity(intent);
		}

	}
	
    private void bindService ()
    {
    	 bindService(new Intent(ITorService.class.getName()),
                 mConnection, Context.BIND_AUTO_CREATE);    	 
    }

    private class ITorServiceConnection implements ServiceConnection {

    	public void onServiceConnected(ComponentName className, IBinder service) {

        	mService = ITorService.Stub.asInterface(service);
    		new GetInfoTask().execute(circuit.fingerPrints);
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mService = null;
        }
    };
    
    private class GetInfoTask extends AsyncTask<List<String>, Integer, List<RouterDescriptor>> {
        
    	@Override
    	protected List<RouterDescriptor> doInBackground(List<String>... fingerPrints) {
    		List<RouterDescriptor> descriptors = new ArrayList<RouterDescriptor>();
    		
            try {
            	for(String fingerPrint : fingerPrints[0]) {
            		descriptors.add(mService.getRouterDescriptor(fingerPrint));
            	}
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			return descriptors;
        }

    	@Override
        protected void onPostExecute(List<RouterDescriptor> descriptors) {
    		circuit.routerDescriptors = descriptors; 
    		
    		List<Map<String, String>> data = new ArrayList<Map<String, String>>();
    		for(RouterDescriptor desc : descriptors) {
    			Map<String, String> entry = new HashMap<String, String>();
    			entry.put("name", desc.name);
    			entry.put("uptime", uptimeToString(desc.uptime));
    			entry.put("bandwidth", bandwidthToString(desc.burstBw));
    			entry.put("avgBandwidth", bandwidthToString(desc.avgBw));
    			entry.put("obsBandwidth", bandwidthToString(desc.observedBw));
    			data.add(entry);
    		}

    		SimpleAdapter routerAdapter = new SimpleAdapter(CircuitStatus.this, data, R.layout.layout_routerrow, 
    										new String[] {"name", "uptime", "bandwidth", "avgBandwidth", "obsBandwidth"},
    										new int[] { R.id.RouterIp, R.id.RouterUptime, R.id.RouterBandwidth, R.id.RouterAvgBandwidth, R.id.RouterObservedBandwidth});
    		
    		ListView routerView = (ListView) findViewById(R.id.Routers);
    		routerView.setAdapter(routerAdapter);
    		routerAdapter.notifyDataSetChanged();
        }
    }
    
    public static String uptimeToString(long seconds) {
    	  String uptime = "";
    	  long mins  = (seconds / 60 % 60);
    	  long hours = (seconds / 3600 % 24);
    	  long days  = (seconds / 86400);

    	  if (days > 0)
    		  uptime += Long.toString(days)+"d";
    	  if (hours > 0)
    		  uptime += Long.toString(hours)+"h";
    	  if (mins > 0)
    		  uptime += Long.toString(mins)+"m";
    	  return uptime;
    }
    

    public static String bandwidthToString(long bytes)
    {
    	if (bytes < 1024)
    		return Long.toString(bytes) + "B/s";
		if (bytes < (1024 * 1024))
			return Long.toString(bytes/1024) + "KB/s";
		if (bytes < (1024 * 1024 * 1024))
			return Long.toString(bytes/(1024 * 1024)) + "MB/s";

		return Long.toString(bytes/(1024 * 1024 * 1024)) + "GB/s";
    }
    
    private ITorService mService;
    private ServiceConnection mConnection;
	private Circuit circuit;
}
